/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * AlgoritmoNUR.java
 *
 * Created on 24/11/2011, 12:29:54
 */
package com.renangomes.malgo.agoritmos;

import com.renangomes.malgo.entidades.Pagina;
import com.renangomes.malgo.gui.JanelaPrincipal;
import java.util.ArrayList;
import javax.swing.JPanel;

/**
 *
 * @author RenanGomes
 */
public class AlgoritmoNUR extends javax.swing.JPanel implements Algo {

    private int faltaDePagina = 0;

    ;

    /** Creates new form AlgoritmoNUR */
    public AlgoritmoNUR() {
        initComponents();
        setVisible(true);
        desc.setSelectionStart(0);
        desc.setSelectionEnd(0);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        tfFalta = new javax.swing.JTextField();
        jSeparator1 = new javax.swing.JSeparator();
        jLabel2 = new javax.swing.JLabel();
        tfC0 = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        tfC1 = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        tfC2 = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        tfC3 = new javax.swing.JTextField();
        jSeparator2 = new javax.swing.JSeparator();
        jScrollPane1 = new javax.swing.JScrollPane();
        desc = new javax.swing.JTextPane();
        jLabel6 = new javax.swing.JLabel();

        jLabel1.setFont(new java.awt.Font("Verdana", 1, 18));
        jLabel1.setText("Faltas de Página:");

        tfFalta.setEditable(false);
        tfFalta.setFont(new java.awt.Font("Verdana", 1, 18));
        tfFalta.setForeground(new java.awt.Color(204, 0, 0));
        tfFalta.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        tfFalta.setText("0");
        tfFalta.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));

        jLabel2.setText("Classe 0 (Não Referenciada e Não Modificada):");

        tfC0.setEditable(false);

        jLabel3.setText("Classe 1 (Não Referênciada e Modificada):");

        tfC1.setEditable(false);

        jLabel4.setText("Classe 2 (Referênciada e Não Modificada):");

        tfC2.setEditable(false);

        jLabel5.setText("Classe 3 (Referênciada e Modificada):");

        tfC3.setEditable(false);

        desc.setContentType("text/html");
        desc.setEditable(false);
        desc.setFont(new java.awt.Font("Verdana", 0, 11));
        desc.setText("<html>\r\n  <head>\r\n\r\n  </head>\r\n  <body style=\"font-family:Verdana, Arial; margin:10px\">\r\n\n      \r\n<h3 style=\"margin-top:0px\" >Algoritmo de substituição de página NÃO USADA RECENTEMENTE (NUR)</h3>\n    <p style=\"text-align: justify\">\n\nA maioria dos computadores com memória virtual tem dois bits de status – o bit referenciada (R) e o bit modificada (M) – associados a cada página virtual, que permitem que o sistema operacional saiba quais páginas físicas estão sendo usadas e quais não estão. O bit R é colocado em 1 sempre que a página é refereciada (lida ou escrita). O bit M é colocado em 1 sempre que se escreve na página (isto é, a página é modificada). Os bits estão contidos em cada entrada da tabela de páginas. É importante perceber que estes bits devem ser atualizados em todas as referências à memória, de modo que é essencial que esta atualização se dê por hardware. Uma vez que um bit é colocado em 1 por hardware, ele permanece em 1 até o sistema operacional coloca-lo em 0 por software.\n</p>\n\n<p style=\"text-align: justify\">\nO algoritmo NUR, <b>remove aleatoriamente uma página da classe de ordem mais baixa</b> que não esteja vazia. Está implícito neste algoritmo que é melhor remover uma página modificada mas não referenciada a pelo menos uma interrupção do relógio do que uma página não modificada que está sendo intensamente referenciada. <b>A principal vantagem do algoritmo NUR é ser fácil de entender e de implementar, e, além disso, fornece um desempenho que, apesar de não ser ótimo, pode ser adequado.</b>\n\n\n\n    </p>\r\n  </body>\r\n</html>\r\n");
        jScrollPane1.setViewportView(desc);

        jLabel6.setText("Descrição do Algoritmo NUR:");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 406, Short.MAX_VALUE)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 406, Short.MAX_VALUE)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 406, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 195, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(tfFalta, javax.swing.GroupLayout.DEFAULT_SIZE, 207, Short.MAX_VALUE))
                    .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3)
                            .addComponent(jLabel4)
                            .addComponent(jLabel5))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(tfC3, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE)
                            .addComponent(tfC2, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE)
                            .addComponent(tfC1, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE)
                            .addComponent(tfC0, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(tfFalta, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(tfC0, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tfC1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tfC2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel5)
                    .addComponent(tfC3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel6)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 86, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextPane desc;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JTextField tfC0;
    private javax.swing.JTextField tfC1;
    private javax.swing.JTextField tfC2;
    private javax.swing.JTextField tfC3;
    private javax.swing.JTextField tfFalta;
    // End of variables declaration//GEN-END:variables

    @Override
    public int decide(Pagina[] men, ArrayList<Integer> cad, int pos) {

        for (int i = 0; i < men.length; i++) {
            if (men[i] == null) {
                return i;
            }

        }


        ArrayList<Pagina> c0 = new ArrayList<Pagina>();
        ArrayList<Pagina> c1 = new ArrayList<Pagina>();
        ArrayList<Pagina> c2 = new ArrayList<Pagina>();
        ArrayList<Pagina> c3 = new ArrayList<Pagina>();




        for (int i = 0; i < men.length; i++) {

            Pagina p = men[i];

            if (!p.isModificada() && !p.isReferenciada()) {
                c0.add(p);
                tfC0.setText(tfC0.getText() + " " + p.getNumero());
            } else {
                if (p.isModificada() && !p.isReferenciada()) {
                    c1.add(p);
                    tfC1.setText(tfC1.getText() + " " + p.getNumero());
                } else {
                    if (!p.isModificada() && p.isReferenciada()) {
                        c2.add(p);
                        tfC2.setText(tfC2.getText() + " " + p.getNumero());
                    } else {
                        c3.add(p);
                        tfC3.setText(tfC3.getText() + " " + p.getNumero());
                    }
                }
            }
        }




        Pagina seraRemovida = null;
        if (!c0.isEmpty()) {
            seraRemovida = c0.get(Math.round((float) Math.random() * (c0.size() - 1)));
        } else {
            if (!c1.isEmpty()) {
                seraRemovida = c1.get(Math.round((float) Math.random() * (c1.size() - 1)));
            } else {
                if (!c2.isEmpty()) {
                    seraRemovida = c2.get(Math.round((float) Math.random() * (c2.size() - 1)));
                } else {
                    seraRemovida = c3.get(Math.round((float) Math.random() * (c3.size() - 1)));
                }
            }
        }


        for (int i = 0; i < men.length; i++) {
            if (men[i].getNumero() == seraRemovida.getNumero()) {
                return i;
            }

        }

        return 0;
    }

    @Override
    public void processar(Pagina[] m, ArrayList<Pagina> dis, ArrayList<Integer> cad, int pos) {

        tfC0.setText("");
        tfC1.setText("");
        tfC2.setText("");
        tfC3.setText("");
        boolean encontrada = false;
        Pagina tmp = null;
        for (Pagina p : dis) {
            if (p != null && p.getNumero() == cad.get(pos)) {
                tmp = p;
                encontrada = true;
            }
        }
        if (encontrada) {
            dis.remove(tmp);
        }
        boolean falta = true;
        for (Pagina p : m) {
            if (p != null && p.getNumero() == cad.get(pos)) {
                falta = false;
            }

        }
        if (falta) {
            faltaDePagina++;
            atualizaGUI();
        }
        for (int i = 0; i < m.length; i++) {
            if (m[i] != null && m[i].getNumero() == cad.get(pos)) {
                return;
            }
        }
        // Decide qual espaço será usado
        int aRemover = decide(m, cad, pos);
        // Se for um espaço ocupado, copia para o disco
        if (m[aRemover] != null && !dis.contains(m[aRemover])) {
            dis.add(m[aRemover]);
        }
        m[aRemover] = new Pagina(cad.get(pos));

    }

    @Override
    public JPanel getPanel() {
        return this;
    }

    private void atualizaGUI() {
        tfFalta.setText(Integer.toString(faltaDePagina));
    }
}
